package com.agricultural.machine.environment;

import com.agricultural.machine.logging.Logger;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.Timer;
import java.util.TimerTask;

/**
 * 环境监测器 - 观察者模式中的被观察者
 * 负责监测环境数据并通知观察者
 */
public class EnvironmentMonitor {
    private static EnvironmentMonitor instance;
    private final List<EnvironmentObserver> observers;
    private final EnvironmentData environmentData;
    private final Logger logger;
    private final Random random;
    private Timer timer;
    private boolean autoMonitoring;
    
    private EnvironmentMonitor() {
        this.observers = new ArrayList<>();
        this.environmentData = new EnvironmentData();
        this.logger = Logger.getInstance();
        this.random = new Random();
        this.autoMonitoring = false;
    }
    
    public static synchronized EnvironmentMonitor getInstance() {
        if (instance == null) {
            instance = new EnvironmentMonitor();
        }
        return instance;
    }
    
    /**
     * 添加观察者
     */
    public void addObserver(EnvironmentObserver observer) {
        if (!observers.contains(observer)) {
            observers.add(observer);
            logger.info("EnvironmentMonitor", "添加环境观察者: " + observer);
        }
    }
    
    /**
     * 删除观察者
     */
    public void removeObserver(EnvironmentObserver observer) {
        observers.remove(observer);
        logger.info("EnvironmentMonitor", "移除环境观察者: " + observer);
    }
    
    /**
     * 通知所有观察者
     */
    private void notifyObservers() {
        for (EnvironmentObserver observer : observers) {
            observer.onEnvironmentChanged(environmentData);
        }
    }
    
    /**
     * 开始自动监测环境
     * @param intervalSeconds 监测间隔（秒）
     */
    public void startAutoMonitoring(int intervalSeconds) {
        if (autoMonitoring) {
            return;
        }
        
        autoMonitoring = true;
        timer = new Timer();
        timer.scheduleAtFixedRate(new TimerTask() {
            @Override
            public void run() {
                updateRandomEnvironmentData();
            }
        }, 0, intervalSeconds * 1000L);
        
        logger.info("EnvironmentMonitor", "启动自动环境监测，间隔: " + intervalSeconds + "秒");
    }
    
    /**
     * 停止自动监测环境
     */
    public void stopAutoMonitoring() {
        if (!autoMonitoring) {
            return;
        }
        
        autoMonitoring = false;
        if (timer != null) {
            timer.cancel();
            timer = null;
        }
        
        logger.info("EnvironmentMonitor", "停止自动环境监测");
    }
    
    /**
     * 更新随机环境数据
     */
    public void updateRandomEnvironmentData() {
        // 随机更新环境数据
        environmentData.setSoilMoisture(20 + random.nextDouble() * 60); // 20%-80%
        environmentData.setSoilPH(5.5 + random.nextDouble() * 3.0); // 5.5-8.5
        environmentData.setSoilNutrients(random.nextDouble() > 0.5 ? "丰富" : "一般");
        environmentData.setTemperature(15 + random.nextDouble() * 25); // 15℃-40℃
        environmentData.setHumidity(30 + random.nextDouble() * 60); // 30%-90%
        environmentData.setWindSpeed(random.nextDouble() * 10); // 0-10m/s
        environmentData.setCropStatus(
                random.nextDouble() > 0.7 ? "良好" : 
                (random.nextDouble() > 0.5 ? "一般" : "需要关注")
        );
        
        // 随机生成障碍物
        if (random.nextDouble() < 0.3) {
            environmentData.setObstacleDetected(true);
            environmentData.setObstacleType(random.nextDouble() > 0.5 ? "岩石" : "树枝");
        } else {
            environmentData.setObstacleDetected(false);
            environmentData.setObstacleType("");
        }
        
        logger.info("EnvironmentMonitor", "环境数据已更新: " + environmentData);
        
        // 通知所有观察者
        notifyObservers();
    }
    
    /**
     * 获取当前环境数据
     */
    public EnvironmentData getEnvironmentData() {
        return environmentData;
    }
    
    /**
     * 手动设置环境数据
     */
    public void setEnvironmentData(double soilMoisture, double soilPH, String soilNutrients,
                                  double temperature, double humidity, double windSpeed,
                                  String cropStatus, boolean obstacleDetected, String obstacleType) {
        environmentData.setSoilMoisture(soilMoisture);
        environmentData.setSoilPH(soilPH);
        environmentData.setSoilNutrients(soilNutrients);
        environmentData.setTemperature(temperature);
        environmentData.setHumidity(humidity);
        environmentData.setWindSpeed(windSpeed);
        environmentData.setCropStatus(cropStatus);
        environmentData.setObstacleDetected(obstacleDetected);
        environmentData.setObstacleType(obstacleType);
        
        logger.info("EnvironmentMonitor", "环境数据已手动设置: " + environmentData);
        
        // 通知所有观察者
        notifyObservers();
    }
} 